#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project ：turbo 
@File    ：logging.py
@Author  ：赵加响
@Date    ：2023/4/28 15:15 
@Desc    ：
"""
import logging
import datetime
import json

from django.contrib.auth.models import AnonymousUser
from django.utils.deprecation import MiddlewareMixin
from rest_framework_simplejwt.backends import TokenBackend

from apps.accounts.models import User
from turbo.settings import SYSTEM_CONFIG

logger = logging.getLogger(__name__)


class RequestResponseLoggingMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if not SYSTEM_CONFIG['global_logging']:
            return self.get_response(request)

        logger = logging.getLogger('django.request')

        request_start_time = datetime.datetime.now()
        try:
            request_body = json.loads(
                str(request.body, encoding='utf-8').replace(' ', '').replace('\n', '').replace('\t', ''))
        except:
            try:
                request_body = request.body.decode('utf-8')
            except:
                request_body = {}

        request_log = {
            'timestamp': request_start_time.isoformat(),
            'user': request.META['USER'],
            'method': request.method,
            'path': request.path,
            'query_params': dict(request.GET),
            'request_body': request_body,
            'remote_address': request.META.get('REMOTE_ADDR', ''),
        }

        response = self.get_response(request)

        # 获取响应内容
        if SYSTEM_CONFIG['resp_data_in_log']:
            if response['content-type'] == 'application/json' and not getattr(response, 'streaming', False):
                try:
                    response_body = json.loads(response.content.decode('utf-8'))
                except ValueError:
                    response_body = 'Invalid JSON'
            else:
                try:
                    response_body = response.data if response.status_code == 200 else response.reason_phrase
                except:
                    response_body = response.reason_phrase
        else:
            response_body = {}

        request_end_time = datetime.datetime.now()
        response_log = {
            'timestamp': request_end_time.isoformat(),
            'status_code': response.status_code,
            'response_headers': dict(response.headers),
            'response_body': response_body,
        }

        try:
            logger.info(f'request: {json.dumps(request_log)}. response: {json.dumps(response_log)}')
        except Exception as e:
            logger.error(str(e))

        return response


class GetRequestUserMiddleware(MiddlewareMixin):

    def process_request(self, request):

        # 获取请求的 username，如果是未登录的则为 AnonymousUser
        if not isinstance(request.user, AnonymousUser):
            username = request.user.username
        else:
            try:
                token = request.headers['Authorization']
                decoded = TokenBackend(algorithm='HS256').decode(token.split(' ')[1], verify=False)
                user_id = decoded['user_id']
                user = User.objects.get(pk=user_id)
                username = user.username
                request.user = user
            except Exception or User.DoesNotExist:
                username = 'AnonymousUser'

        request.META['USER'] = username
